package wang.lx.mybatis.cfg;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.Filter;

import org.apache.shiro.authz.Authorizer;
import org.apache.shiro.authz.ModularRealmAuthorizer;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import wang.lx.mybatis.shiro.JwtAuthenticationFilter;
import wang.lx.mybatis.shiro.JwtRealm;
import wang.lx.mybatis.shiro.MyRealm;

@Configuration
public class ShiroConfiguration {
    
    //@Bean("authorizer")
    @Bean
    public MyRealm myRealm() {
        return new MyRealm();
    }

    @Bean
    public JwtRealm jwtRealm() {
        return new JwtRealm();
    }

    @Bean
    public Authorizer authorizer(List<Realm> realms) {
        ModularRealmAuthorizer authorizer = new ModularRealmAuthorizer();

        //if (permissionResolver != null) {
            //authorizer.setPermissionResolver(permissionResolver);
        //}

        //if (rolePermissionResolver != null) {
            //authorizer.setRolePermissionResolver(rolePermissionResolver);
        //}
        authorizer.setRealms(realms);
        return authorizer;
    }
    /*
    protected SessionsSecurityManager createSecurityManager() {
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        securityManager.setSubjectDAO(subjectDAO());
        securityManager.setSubjectFactory(subjectFactory());

        RememberMeManager rememberMeManager = rememberMeManager();
        if (rememberMeManager != null) {
            securityManager.setRememberMeManager(rememberMeManager);
        }

        return securityManager;
    }

    @Bean
    public SessionsSecurityManager securityManager(List<Realm> realms) {
        SessionsSecurityManager securityManager = createSecurityManager();
        securityManager.setAuthenticator(authenticator());
        securityManager.setAuthorizer(authorizer());
        securityManager.setRealms(realms);
        securityManager.setSessionManager(sessionManager());
        securityManager.setEventBus(eventBus);

        if (cacheManager != null) {
            securityManager.setCacheManager(cacheManager);
        }

        return securityManager;
    }
    */

    @Bean
    public ShiroFilterChainDefinition  shiroFilterChainDefinition(){
        DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
        // logged in users with the 'admin' role
        chainDefinition.addPathDefinition("/admin/**", "authc, roles[admin]");

        // logged in users with the 'document:read' permission
        //chainDefinition.addPathDefinition("/docs/**", "authc, perms[document:read]");

        // all other paths require a logged in user
        chainDefinition.addPathDefinition("/login/", "anon");
        chainDefinition.addPathDefinition("/login/logout", "logout");
        chainDefinition.addPathDefinition("/**", "jwt");
        return chainDefinition;
    }

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(org.apache.shiro.mgt.SecurityManager securityManager,ShiroFilterChainDefinition shiroFilterChainDefinition) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        // 添加JWT过滤器
        Map<String, Filter> filters = new HashMap<>();
        filters.put("jwt", new JwtAuthenticationFilter());
        shiroFilterFactoryBean.setFilters(filters);
        /*
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        // 公开接口
        filterChainDefinitionMap.put("/api/auth/login", "anon");
        filterChainDefinitionMap.put("/api/auth/register", "anon");
        
        // 需要认证的接口
        filterChainDefinitionMap.put("/api/**", "jwt");
        
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        */
        shiroFilterFactoryBean.setFilterChainDefinitionMap(shiroFilterChainDefinition.getFilterChainMap());
        shiroFilterFactoryBean.setLoginUrl("/login");
        return shiroFilterFactoryBean;
    }
}
